package com.onenine.app.fragment;

import android.app.Fragment;
import android.os.Build;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.os.Looper;
import android.os.MessageQueue;
import android.support.annotation.Nullable;
import android.text.Editable;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.EditText;
import android.widget.TextView;

import com.onenine.app.R;
import com.onenine.app.activity.LoginActivity;
import com.onenine.app.activity.MainActivity;
import com.onenine.app.event.FinishEvent;
import com.onenine.app.listener.OnLoginListener;
import com.onenine.app.request.GetBoundCodeRequest;
import com.onenine.app.request.GetCodeRequest;
import com.onenine.app.request.PhoneBindRequest;
import com.onenine.app.request.PhoneLoginRequest;
import com.onenine.app.response.GetCodeResponse;
import com.onenine.app.response.LoginResponse;
import com.onenine.app.utils.CHelper;
import com.onenine.app.utils.DataType;
import com.onenine.app.utils.UrlConfig;
import com.onenine.app.view.LoadingButton;
import com.onenine.app.view.uppanel.SlidingUpPanelLayout;
import com.onenine.base.okhttp.BaseResponse;
import com.onenine.base.okhttp.OkCallback;
import com.onenine.base.okhttp.OkRequest;
import com.onenine.base.utils.Toasty;
import com.onenine.chat.rongcloud.RcUser;
import com.onenine.common.util.ActivityUtils;
import com.onenine.common.util.FragmentUtils;
import com.onenine.common.util.KeyboardUtils;

import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;

public class LoginSmsFragment extends Fragment implements TextWatcher
        , View.OnKeyListener, View.OnClickListener {

    private final int MAX_SMS_COUNT = 4;
    private StringBuilder mSmsDigit = new StringBuilder(MAX_SMS_COUNT);
    private TextView[] mTvSms = new TextView[MAX_SMS_COUNT];
    private EditText mEditSms;
    private TextView mTvTimer;
    private LoadingButton mBtnLoading;
    private View mLytSendAgain, mTvSendAgain;
    private String mPhoneNum, mOpenId, mUserId;
    private CountDownTimer mCountDownTimer;
    private OnLoginListener mOnLoginListener;
    private LoginResponse mLoginResponse;

    public static Fragment newInstance(String phone) {
        return newInstance(phone, null, null);
    }

    public static Fragment newInstance(String phone, String userId, String openId) {
        Fragment fragment = new LoginSmsFragment();
        Bundle args = new Bundle();
        args.putString("phone", phone);
        args.putString("userId", userId);
        args.putString("openId", openId);
        fragment.setArguments(args);
        return fragment;
    }

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        EventBus.getDefault().register(this);
        mPhoneNum = getArguments().getString("phone");
        mOpenId = getArguments().getString("openId");
        mUserId = getArguments().getString("userId");
        Looper.myQueue().addIdleHandler(new MessageQueue.IdleHandler() {
            @Override
            public boolean queueIdle() {
                startSixtyCountDownTimer();
                return false;
            }
        });

    }

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) {
        mOnLoginListener = (OnLoginListener) getActivity();
        View view = inflater.inflate(R.layout.fragment_login_sms, container, false);
        mTvTimer = view.findViewById(R.id.tv_timer);
        mEditSms = view.findViewById(R.id.edt_sms);
        mBtnLoading = view.findViewById(R.id.btn_loading);
        mBtnLoading.setButtonEnable(false);
        mBtnLoading.setButtonText(R.string.next_step);
        mLytSendAgain = view.findViewById(R.id.ll_send_again);
        mTvSendAgain = view.findViewById(R.id.tv_send_again);
        mTvSms[0] = view.findViewById(R.id.tv_sms1);
        mTvSms[1] = view.findViewById(R.id.tv_sms2);
        mTvSms[2] = view.findViewById(R.id.tv_sms3);
        mTvSms[3] = view.findViewById(R.id.tv_sms4);
        mEditSms.addTextChangedListener(this);
        mEditSms.setOnKeyListener(this);
        mBtnLoading.setButtonOnClickListener(this);
        mTvSendAgain.setOnClickListener(this);
        clearOldSms();
        requestUpPanelExpand();
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {
            //小于7.0以下主动请求焦点
            mEditSms.requestFocus();
        }
        return view;
    }

    @Override
    public void beforeTextChanged(CharSequence s, int start, int count, int after) {

    }

    @Override
    public void onTextChanged(CharSequence s, int start, int before, int count) {

    }

    @Override
    public void afterTextChanged(Editable s) {
        if ("".equals(s.toString())) {
            return;
        }
        if (mSmsDigit.length() > MAX_SMS_COUNT - 1) {
            mEditSms.setText("");
            return;
        }
        mSmsDigit.append(s);
        mEditSms.setText("");
        for (int i = 0; i < mSmsDigit.length(); i++) {
            mTvSms[i].setText("" + mSmsDigit.charAt(i));
        }
        mBtnLoading.setButtonEnable(mSmsDigit.length() == MAX_SMS_COUNT);
    }

    @Override
    public boolean onKey(View v, int keyCode, KeyEvent event) {
        if (event.getAction() == KeyEvent.ACTION_DOWN
                && keyCode == KeyEvent.KEYCODE_DEL) {
            int length = mSmsDigit.length();
            if (length > 0) {
                mSmsDigit.delete(length - 1, length);
                length--;
                mTvSms[length].setText("");
                mBtnLoading.setButtonEnable(false);
                return true;
            }
        }
        return false;
    }

    /**
     * 启动一分钟计时
     */
    private void startSixtyCountDownTimer() {
        mLytSendAgain.setVisibility(View.GONE);
        mTvTimer.setVisibility(View.VISIBLE);
        mCountDownTimer = new CountDownTimer(60_100, 1000) {
            @Override
            public void onTick(long millisUntilFinished) {
                mTvTimer.setText(millisUntilFinished / 1000 + "s");
            }

            @Override
            public void onFinish() {
                mTvTimer.setVisibility(View.GONE);
                mLytSendAgain.setVisibility(View.VISIBLE);
            }
        }.start();
    }

    @Override
    public void onClick(View v) {
        if (v.getId() == R.id.tv_send_again) {
            if (mOpenId == null) {
                getSmsCode();
            } else {
                getBoundSmsCode();
            }
        } else if (v.getId() == R.id.btn_opt) {
            if (mOpenId != null) {
                phoneBind(mSmsDigit.toString());
            } else {
                phoneLogin(mSmsDigit.toString());
            }
        }
    }

    /**
     * 清空旧验证码
     */
    private void clearOldSms() {
        mEditSms.setText("");
        mSmsDigit.setLength(0);
        for (int i = 0; i < MAX_SMS_COUNT; i++) {
            mTvSms[i].setText("");
        }
    }

    /**
     * 展开面板
     */
    private void requestUpPanelExpand() {
        SlidingUpPanelLayout upPanelLayout = mOnLoginListener.getUpPanelLayout();
        upPanelLayout.setPanelState(SlidingUpPanelLayout.PanelState.EXPANDED);
        KeyboardUtils.showSoftInput(getActivity());
        mEditSms.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mEditSms.requestFocus();
                KeyboardUtils.showSoftInput(getActivity());
                upPanelLayout.setPanelState(SlidingUpPanelLayout.PanelState.EXPANDED);
            }
        });
    }

    /**
     * 获取手机验证码
     */
    private void getSmsCode() {
        mBtnLoading.setLoading(true);
        OkRequest.getInstance().withRequest(new GetCodeRequest(mPhoneNum))
                .withUrl(UrlConfig.SEND_CODE).doRequest(LoginActivity.class.getSimpleName(), new OkCallback<GetCodeResponse>() {
            @Override
            public void onResponse(GetCodeResponse response, String srcData) {
                if (response.isSuccess()) {
                    //FIXME 吐司上线后要删除
                    if (!CHelper.isReleaseEnv()) {
                        Toasty.showNormal("验证码：" + response.getSendCode());
                    }
                    clearOldSms();
                    startSixtyCountDownTimer();
                } else {
                    Toasty.showNormal(response.getMessage());
                }
                mBtnLoading.setLoading(false);
            }
        });
    }

    /**
     * 获取绑定手机的短信验证码
     */
    private void getBoundSmsCode() {
        mBtnLoading.setLoading(true);
        OkRequest.getInstance().withRequest(new GetBoundCodeRequest(mPhoneNum, mOpenId))
                .withUrl(UrlConfig.BIND_SEND_CODE).doRequest(LoginActivity.class.getSimpleName(), new OkCallback<GetCodeResponse>() {
            @Override
            public void onResponse(GetCodeResponse response, String srcData) {
                if (response.isSuccess()) {
                    //FIXME 吐司上线后要删除
                    if (!CHelper.isReleaseEnv()) {
                        Toasty.showNormal("验证码：" + response.getSendCode());
                    }
                    clearOldSms();
                    startSixtyCountDownTimer();
                } else {
                    Toasty.showNormal(response.getMessage());
                }
                mBtnLoading.setLoading(false);
            }
        });
    }


    /**
     * 手机绑定
     *
     * @param smsCode
     */
    private void phoneBind(final String smsCode) {
        mBtnLoading.setLoading(true);
        PhoneBindRequest request = new PhoneBindRequest();
        request.setOpenId(mOpenId);
        request.setPhoneNum(mPhoneNum);
        request.setSendCode(smsCode);
        OkRequest.getInstance().withRequest(request)
                .withUrl(UrlConfig.PHONE_BIND).doRequest(getClass().getSimpleName(), new OkCallback<BaseResponse>() {
            @Override
            public void onResponse(BaseResponse response, String srcData) {
                if (response.isSuccess()) {
                    RcUser.getInstance().setUserId(mUserId)
                            .applyUser();
                    cancelCountDownTimer();
                    launchMainActivity();
                } else {
                    Toasty.showNormal(response.getMessage());
                }
                mBtnLoading.setLoading(false);
            }
        });
    }

    /**
     * 手机登录
     *
     * @param smsCode 4位验证码
     */
    private void phoneLogin(final String smsCode) {
        mBtnLoading.setLoading(true);
        PhoneLoginRequest request = new PhoneLoginRequest();
        request.setPhoneNum(mPhoneNum);
        request.setSendCode(smsCode);
        OkRequest.getInstance().withRequest(request)
                .withUrl(UrlConfig.PHONE_LOGIN).doRequest(getClass().getSimpleName(), new OkCallback<LoginResponse>() {
            @Override
            public void onResponse(LoginResponse response, String srcData) {
                if (response.isSuccess()) {
                    mLoginResponse = response;
                    if (response.getSex() > 0 && !TextUtils.isEmpty(response.getPhoto())) {
                        //资料已完善进入主界面
                        saveUserInfo();
                        launchMainActivity();
                    } else {
                        //个人资料未完善
                        FragmentUtils.replace(getFragmentManager()
                                , LoginInputInfoFragment.newInstance(response.getUserId()), R.id.fl_content, true);
                    }
                    cancelCountDownTimer();
                } else {
                    Toasty.showNormal(response.getMessage());
                }
                mBtnLoading.setLoading(false);
            }
        });
    }

    /**
     * 进入主界面
     */
    private void launchMainActivity() {
        KeyboardUtils.hideSoftInput(getActivity());
        EventBus.getDefault().post(new FinishEvent(true));
        ActivityUtils.startActivity(getActivity(), MainActivity.class);
        mOnLoginListener.finishActivity();
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onEvent(FinishEvent event) {
        if (event.isFinish) {
            saveUserInfo();
        }
    }

    /**
     * 保存用户信息
     */
    private void saveUserInfo() {
        if (mLoginResponse != null) {
            RcUser.getInstance()
                    .setUserId(mLoginResponse.getUserId())
                    .setLoginType(DataType.PHONE_LOGIN)
                    .setSex(mLoginResponse.getSex())
                    .applyUser();
        }
    }

    /**
     * 取消倒计时
     */
    private void cancelCountDownTimer() {
        if (mCountDownTimer != null) {
            mCountDownTimer.cancel();
            mCountDownTimer = null;
        }
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        EventBus.getDefault().unregister(this);
    }

}
